<template>
  <div class="page">
    <div class="page-header">
      <h2>销售订单管理</h2>
      <div class="actions">
        <button class="btn btn-primary" @click="openAdd">新增</button>
        <button class="btn btn-primary" @click="onSubmitConfirm" :disabled="selectedIds.length===0">提交审核</button>
        <button class="btn btn-primary" @click="smartPrint" :disabled="isPrinting || selectedIds.length === 0">
          {{ isPrinting ? '🔄 生成中...' : '🖨️ 打印' }}
        </button>
        <button class="btn danger" :disabled="selectedIds.length===0" @click="batchDelete">批量删除</button>
      </div>
    </div>

    <div class="search">
      <input class="ipt" placeholder="请输入客户名称" v-model.trim="query.customerName" @keyup.enter="onSearch" />
      <input class="ipt" placeholder="请输入销售单号" v-model.trim="query.soCode" @keyup.enter="onSearch" />
      <select class="ipt" v-model="query.status">
        <option value="">请选择</option>
        <option value="0">未提交</option>
        <option value="1">审核中</option>
        <option value="2">已完成</option>
        <option value="3">审核拒绝</option>
      </select>
      <div class="date-range">
        <input class="ipt" type="date" v-model="query.startDate" placeholder="开始时间"/>
        <span class="date-separator">至</span>
        <input class="ipt" type="date" v-model="query.endDate" placeholder="结束时间"/>
      </div>
      <button class="btn btn-primary" @click="onSearch">查询</button>
      <button class="btn" @click="reset">重置</button>
    </div>

    <div class="table-wrap">
      <table>
        <thead>
          <tr>
            <th style="width:44px;"><input type="checkbox" v-model="allChecked" @change="toggleAll"/></th>
            <th>销售单号</th>
            <th>提交时间</th>
            <th>客户名称</th>
            <th class="num">订单金额</th>
            <th>审核状态</th>
            <th class="num">实收金额</th>
            <th>联系电话</th>
            <th>收货地址</th>
            <th>销售负责人</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="o in listSorted" :key="o.id" :class="rowClass(o)" @click="selectOne(o.id)">
            <td><input type="checkbox" :value="o.id" v-model="selectedIds" @click.stop/></td>
            <td>{{ o.soCode || 'XS-001' }}</td>
            <td>{{ formatDate(o.createdAt) }}</td>
            <td>{{ o.customerName || customerName(o.customerId) }}</td>
            <td class="num">{{ formatAmount(o.totalAmount) }}</td>
            <td>
              <span :class="['status', getStatusClass(o.status)]">{{ statusText(o.status) }}</span>
            </td>
            <td class="num">{{ formatAmount(o.receivedAmount) }}</td>
            <td>{{ o.contactPhone || '-' }}</td>
            <td>{{ o.shippingAddress || '-' }}</td>
            <td>{{ o.salesRep || '-' }}</td>
            <td>
              <button class="btn sm" @click.stop="openRowDetail(o)">详情</button>
              <button class="btn sm" @click.stop="edit(o)" :disabled="!(o.status===0 || o.status===3)">编辑</button>
              <button class="btn sm btn-print" @click.stop="printSingleOrder(o)" :disabled="isPrinting">
                {{ isPrinting ? '🔄' : '🖨️ 打印' }}
              </button>
              <button class="btn sm danger" @click.stop="delOne(o)" :disabled="o.status!==0">删除</button>
            </td>
          </tr>
        </tbody>
      </table>
      <div class="pager">
        <button class="btn sm" :disabled="page.current===1" @click="go(page.current-1)">上一页</button>
        <span>{{ page.current }} / {{ totalPages }}</span>
        <button class="btn sm" :disabled="page.current===totalPages" @click="go(page.current+1)">下一页</button>
      </div>
    </div>

    <!-- 新增/编辑订单对话框 -->
    <div v-if="showModal" class="modal" @click.self="close">
      <div class="dialog dialog-fixed">
        <h3>{{ editing? '编辑销售订单' : '新增销售订单' }}</h3>
        <div class="form-grid">
          <label>客户名称
            <div class="customer-select-wrapper">
              <input 
                class="ipt" 
                placeholder="搜索客户名称或编码" 
                v-model="customerSearchKeyword"
                @input="filterCustomers"
              />
              <select v-model="form.customerId" @change="onCustomerChange">
                <option :value="null">请选择客户</option>
                <option v-for="c in filteredCustomerOptions" :key="c.id" :value="c.id">
                  {{ formatCustomerDisplay(c) }}
                </option>
              </select>
            </div>
          </label>
          <label>联系电话<input v-model="form.contactPhone" placeholder="请输入联系电话"/></label>
          <label>地区
            <select v-model="form.region">
              <option value="">请选择</option>
              <option value="新疆">新疆</option>
              <option value="江苏">江苏</option>
              <option value="北京">北京</option>
            </select>
          </label>
          <label>详细地址<input v-model="form.shippingAddress" placeholder="请输入详细地址"/></label>
          <label>销售负责人<input v-model="form.salesRep" placeholder="请输入销售负责人"/></label>
          <label>负责人电话<input v-model="form.respPhone" placeholder="请输入负责人电话"/></label>
          <label>销售日期<input v-model="form.saleDate" type="date"/></label>
          <label>发货日期<input v-model="form.expectedShipDate" type="date"/></label>
          <label class="col-2">备注<input v-model="form.remark" placeholder="请输入备注"/></label>
        </div>

        <div class="section">
          <div class="section-header">
            <span>选择商品</span>
            <button class="btn btn-primary" @click="openProductPicker">关联商品</button>
          </div>
          <table>
            <thead>
              <tr>
                <th>商品名称</th>
                <th>规格型号</th>
                <th>单位</th>
                <th>销售数量</th>
                <th>销售单价（元）</th>
                <th>折扣%</th>
                <th>折后价（元）</th>
                <th>实收金额(元)</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(it,idx) in form.items" :key="it.skuId">
                <td>{{ it.name }}</td>
                <td>{{ it.spec }}</td>
                <td>{{ it.unit || '箱' }}</td>
                <td class="qty">
                  <button class="btn sm" @click="changeQty(idx,-1)">-</button>
                  <input class="ipt ipt-sm" type="number" v-model.number="it.qty" min="0"/>
                  <button class="btn sm" @click="changeQty(idx,1)">+</button>
                </td>
                <td><input class="ipt ipt-sm" type="number" v-model.number="it.price" step="0.01"/></td>
                <td><input class="ipt ipt-sm" type="number" v-model.number="it.discount" step="1"/></td>
                <td class="num">{{ formatAmount(discountPrice(it)) }}</td>
                <td class="num">{{ formatAmount(lineAmount(it)) }}</td>
                <td><a class="link danger" @click="removeItem(idx)">删除</a></td>
              </tr>
              <tr v-if="form.items.length===0">
                <td colspan="9" style="text-align:center;color:#999;">请点击"关联商品"选择商品</td>
              </tr>
            </tbody>
          </table>

          <div class="order-summary">
            <div>
              <label>整单价格</label>
              <input class="ipt" type="number" v-model.number="form.manualTotal" placeholder="可选，手动覆盖总价"/>
            </div>
            <div>
              <label>整单折扣%</label>
              <input class="ipt" type="number" v-model.number="form.orderDiscount"/>
            </div>
            <div>
              <label>整单成交额（元）</label>
              <input class="ipt" :value="formatAmount(orderAmount)" disabled />
            </div>
          </div>
        </div>

        <div class="dialog-actions">
          <button class="btn" @click="close">取消</button>
          <button class="btn btn-primary" @click="save">保存</button>
        </div>
      </div>
    </div>

    <!-- 订单详情对话框 -->
    <div v-if="showDetail" class="modal" @click.self="showDetail=false">
      <div class="dialog dialog-fixed">
        <div class="detail-header">
          <div class="detail-title">{{ current?.soCode || 'SH00001' }}</div>
          <button class="btn sm" @click="showDetail=false">关闭</button>
        </div>

    <!-- 成功提示弹窗 -->
    <div v-if="showSuccess" class="modal" @click.self="showSuccess=false">
      <div class="success">
        <h3>操作成功</h3>
        <p>{{ successMessage }}</p>
        <div class="confirm-actions">
          <button class="btn btn-primary" @click="showSuccess=false">知道了</button>
        </div>
      </div>
    </div>

    <!-- 打印预览弹框 -->
    <div v-if="showPrintPreview" class="modal" @click.self="showPrintPreview=false">
      <div class="print-preview">
        <div class="preview-header">
          <h3>打印预览</h3>
          <button class="btn sm" @click="showPrintPreview=false">关闭</button>
        </div>
        <div class="preview-content">
          <div class="preview-info">
            <p><strong>订单数量：</strong>{{ printPreviewData.length }} 个</p>
            <p><strong>订单编号：</strong>{{ printPreviewData.map(o => o.soCode || o.id).join(', ') }}</p>
          </div>
                      <div class="preview-actions">
              <button class="btn" @click="showPrintPreview=false" :disabled="isPrinting">取消</button>
              <button class="btn btn-primary" @click="confirmPrint" :disabled="isPrinting">
                {{ isPrinting ? '🔄 生成中...' : '确认打印' }}
              </button>
            </div>
        </div>
      </div>
    </div>
        <div class="summary">
          <div class="card">
            <div class="label">采购金额（元）</div>
            <div class="value">{{ formatAmount(current?.purchaseAmount || current?.totalAmount || 0).replace('¥','') }}</div>
          </div>
          <div class="card">
            <div class="label">采购日期</div>
            <div class="value">{{ formatDate(current?.createdAt) }}</div>
          </div>
          <div class="card">
            <div class="label">审批状态</div>
            <div class="value">{{ statusText(current?.status) }}</div>
          </div>
          <div class="card">
            <div class="label">付款状态</div>
            <div class="value">{{ current?.paymentStatusText || '全部付款' }}</div>
          </div>
          <div class="card">
            <div class="label">已付款金额</div>
            <div class="value">{{ (current?.paidAmount!=null? current.paidAmount : 23333) }}</div>
          </div>
          <div class="card">
            <div class="label">备注</div>
            <div class="value">{{ current?.remark || '—' }}</div>
          </div>
        </div>

        <div class="tabs">
          <div :class="['tab', detailTab==='base' && 'active']" @click="detailTab='base'">基础信息</div>
          <div :class="['tab', detailTab==='items' && 'active']" @click="detailTab='items'">销售商品</div>
          <div :class="['tab', detailTab==='flow' && 'active']" @click="detailTab='flow'">审批流程</div>
          <div :class="['tab', detailTab==='stock' && 'active']" @click="detailTab='stock'">出库情况</div>
          <div :class="['tab', detailTab==='payments' && 'active']" @click="detailTab='payments'">销售回款</div>
          <div :class="['tab', detailTab==='returns' && 'active']" @click="detailTab='returns'">退货记录</div>
        </div>

        <div class="tab-pane" v-if="detailTab==='base'">
          <div class="base-grid">
            <label>销售单号<input disabled :value="current?.soCode || 'CJ000001'"/></label>
            <label>销售金额<input disabled :value="formatAmount(current?.totalAmount||6552.76)"/></label>
            <label>下单日期<input disabled :value="formatDate(current?.createdAt)"/></label>
            <label>发货日期<input disabled :value="formatDate(current?.expectedShipDate)"/></label>
            <label>客户名称<input disabled :value="current?.customerName || customerName(current?.customerId)"/></label>
            <label>联系电话<input disabled :value="current?.contactPhone || '—'"/></label>
            <label>地区<input disabled :value="current?.region || '—'"/></label>
            <label>详细地址<input disabled :value="current?.shippingAddress || '—'"/></label>
            <label>销售负责人<input disabled :value="current?.salesRep || '—'"/></label>
            <label>负责人电话<input disabled :value="current?.respPhone || '—'"/></label>
            <label>订单状态<input disabled :value="statusText(current?.status)"/></label>
            <label class="col-2">备注<input disabled :value="current?.remark || '———'"/></label>
            <label>创建人<input disabled :value="current?.creator || '—'"/></label>
            <label>创建时间<input disabled :value="formatDate(current?.createdAt)"/></label>
            <label>修改人<input disabled :value="current?.updater || '—'"/></label>
            <label>修改时间<input disabled :value="formatDate(current?.updatedAt)"/></label>
          </div>
        </div>

        <div class="tab-pane" v-if="detailTab==='items'">
          <table>
            <thead>
              <tr>
                <th>序号</th>
                <th>商品名称</th>
                <th>规格型号</th>
                <th>销售数量</th>
                <th>单价</th>
                <th>折扣</th>
                <th>折后价</th>
                <th>销售金额</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(it,idx) in (current?.items||[])" :key="idx">
                <td>{{ idx+1 }}</td>
                <td>{{ it.name }}</td>
                <td>{{ it.spec || it.skuId }}</td>
                <td>{{ it.qty }}</td>
                <td>{{ it.price }}</td>
                <td>{{ (it.discount||0) + '%' }}</td>
                <td>{{ discountPrice(it).toFixed(2) }}</td>
                <td>{{ lineAmount(it).toFixed(2) }}</td>
              </tr>
              <tr v-if="!current || (current.items||[]).length===0">
                <td colspan="8" style="text-align:center;color:#999;">暂无商品</td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="tab-pane" v-if="detailTab==='flow'">
          <div class="flow-list">
            <div class="flow-item" v-for="(f,idx) in (current?.approvals||mockApprovals)" :key="idx">
              <div :class="['flow-icon', f.status==='pass'?'ok': (f.status==='reject'?'no':'wait')]">{{ f.status==='pass'?'✓': (f.status==='reject'?'✕':'✎') }}</div>
              <div class="flow-chip" :class="{ pass:f.status==='pass', reject:f.status==='reject', wait:f.status==='wait' }">{{ f.title }}</div>
              <div class="flow-col">{{ f.user }}</div>
              <div class="flow-col">{{ f.dept }}</div>
              <div class="flow-col">{{ f.role }}</div>
              <div class="flow-col">{{ f.date }}</div>
              <div class="flow-col">{{ f.remark || (f.status==='reject'?'采购金额有问题，请核查':'同意') }}</div>
            </div>
          </div>
        </div>

        <div class="tab-pane" v-if="detailTab==='stock'">
          <div class="stock-actions">
            <input class="ipt" placeholder="商品名称/入库单号/规格型号" />
            <div style="margin-left:10px;">显示：</div>
            <button class="btn sm">全部入库</button>
            <button class="btn sm">部分入库</button>
            <button class="btn sm">待入库</button>
          </div>
          <table>
            <thead>
              <tr>
                <th>序号</th>
                <th>商品名称</th>
                <th>规格型号</th>
                <th>单位</th>
                <th>入库状态</th>
                <th>采购数量</th>
                <th>已入库数量</th>
                <th>待入库数量</th>
                <th>入库单号</th>
                <th>入库人</th>
                <th>入库时间</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(s,idx) in (current?.stocks||mockStocks)" :key="idx">
                <td>{{ idx+1 }}</td>
                <td>{{ s.name }}</td>
                <td>{{ s.spec }}</td>
                <td>{{ s.unit }}</td>
                <td :class="['badge', s.status]">{{ s.statusText }}</td>
                <td>{{ s.qty }}</td>
                <td>{{ s.inQty }}</td>
                <td>{{ s.waitQty }}</td>
                <td>{{ s.billNo }}</td>
                <td>{{ s.user }}</td>
                <td>{{ s.time }}</td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="tab-pane" v-if="detailTab==='payments'">
          <div class="table-wrap-in">
            <input class="ipt" placeholder="付款单号/付款方式" />
            <table>
              <thead>
                <tr>
                  <th>序号</th>
                  <th>回款单号</th>
                  <th>回款金额</th>
                  <th>回款方式</th>
                  <th>回款时间</th>
                  <th>审批状态</th>
                  <th>审批人</th>
                  <th>备注</th>
                  <th>创建人</th>
                  <th>创建时间</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(p,idx) in (current?.payments||mockPayments)" :key="idx">
                  <td>{{ idx+1 }}</td>
                  <td>{{ p.no }}</td>
                  <td>{{ p.amount }}</td>
                  <td>{{ p.method }}</td>
                  <td>{{ p.time }}</td>
                  <td class="green">审批完成</td>
                  <td>{{ p.approver }}</td>
                  <td>---</td>
                  <td>{{ p.creator }}</td>
                  <td>{{ p.createTime }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>

        <div class="tab-pane" v-if="detailTab==='returns'">
          <div class="table-wrap-in">
            <input class="ipt" placeholder="退货单号/付款方式" />
            <table>
              <thead>
                <tr>
                  <th>序号</th>
                  <th>销售退货单号</th>
                  <th>退货金额</th>
                  <th>付款方式</th>
                  <th>付款时间</th>
                  <th>审批状态</th>
                  <th>审批人</th>
                  <th>备注</th>
                  <th>创建人</th>
                  <th>创建时间</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(r,idx) in (current?.returns||mockReturns)" :key="idx">
                  <td>{{ idx+1 }}</td>
                  <td><a class="link">{{ r.no }}</a></td>
                  <td>{{ r.amount }}</td>
                  <td>{{ r.method }}</td>
                  <td>{{ r.time }}</td>
                  <td class="green">审批完成</td>
                  <td>{{ r.approver }}</td>
                  <td>---</td>
                  <td>{{ r.creator }}</td>
                  <td>{{ r.createTime }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>

    <!-- 提交审核确认弹窗 -->
    <div v-if="showSubmitConfirm" class="confirm-mask" @click.self="showSubmitConfirm=false">
      <div class="confirm">
        <div class="confirm-title">提示</div>
        <div class="confirm-body">确认提交审核已选择的销售单据嘛?</div>
        <div class="confirm-actions">
          <button class="btn" @click="showSubmitConfirm=false">取消</button>
          <button class="btn btn-primary" @click="submitForReview">确认</button>
        </div>
      </div>
    </div>

    <!-- 关联商品弹窗（左右穿梭） -->
    <div v-if="showProductPicker" class="modal" @click.self="closeProductPicker">
      <div class="dialog dialog-xl product-picker-dialog">
        <h3>选择商品</h3>
        <div class="picker">
          <div class="picker-pane">
            <div class="picker-search">
              <input class="ipt" placeholder="请输入商品名称/编号" v-model="productKeyword" />
            </div>
            <table>
              <thead>
                <tr>
                  <th style="width:40px"><input type="checkbox" v-model="leftAllChecked" @change="toggleLeftAll"/></th>
                  <th>商品名称</th>
                  <th>商品编号</th>
                  <th>商品规格</th>
                  <th style="width:80px">操作</th>
                </tr>
              </thead>
              <tbody>
                <tr v-if="productLoading">
                  <td colspan="5" style="text-align: center; color: #666; padding: 20px;">
                    <div style="display: flex; align-items: center; justify-content: center; gap: 8px;">
                      <div class="loading-spinner"></div>
                      正在加载商品...
                    </div>
                  </td>
                </tr>
                <tr v-else v-for="p in filteredCandidates" :key="p.skuId">
                  <td><input type="checkbox" :value="p.skuId" v-model="leftSelected"/></td>
                  <td>{{ p.name }}</td>
                  <td>{{ p.code }}</td>
                  <td>{{ p.spec }}</td>
                  <td><button class="btn sm btn-primary" @click="addCandidate(p)">添加</button></td>
                </tr>
                <tr v-if="!productLoading && filteredCandidates.length === 0">
                  <td colspan="5" style="text-align: center; color: #999; padding: 20px;">
                    {{ productKeyword ? '未找到匹配的商品' : '请输入关键词搜索商品' }}
                  </td>
                </tr>
              </tbody>
            </table>
            <div class="picker-pager">
              <button class="btn sm" :disabled="productPage.current===1" @click="productPage.current--; loadProducts()">上一页</button>
              <span>{{ productPage.current }} / {{ Math.max(1, Math.ceil((productPage.total||0)/productPage.size)) }}</span>
              <button class="btn sm" :disabled="productPage.current>=Math.ceil((productPage.total||0)/productPage.size)" @click="productPage.current++; loadProducts()">下一页</button>
              <span>共 {{ productPage.total||0 }} 条</span>
            </div>
          </div>
          <div class="picker-actions">
            <button class="btn btn-primary circle" @click="moveToRight">»</button>
            <button class="btn circle" @click="moveToLeft">«</button>
          </div>
          <div class="picker-pane">
            <table>
              <thead>
                <tr>
                  <th style="width:40px"><input type="checkbox" v-model="rightAllChecked" @change="toggleRightAll"/></th>
                  <th>商品名称</th>
                  <th>商品编号</th>
                  <th>商品规格</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="p in pickedProducts" :key="p.skuId">
                  <td><input type="checkbox" :value="p.skuId" v-model="rightSelected"/></td>
                  <td>{{ p.name }}</td>
                  <td>{{ p.code }}</td>
                  <td>{{ p.spec }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <div class="dialog-actions">
          <button class="btn" @click="closeProductPicker">取消</button>
          <button class="btn btn-primary" @click="confirmPick">确认</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, watch } from 'vue'
import { getOrderPage, createFullOrder, updateFullOrder, deleteOrderBatch, getFullOrderDetail, getCustomerDetail, getCustomerPage, getSkuPage, printOrdersBatch, getOrderPrintData } from '@/api/sales'

const query = reactive({
  customerName: '',
  soCode: '',
  status: '',
  startDate: '',
  endDate: ''
})
const list = ref([])
const page = reactive({ current:1, size:10, total:0 })
const totalPages = computed(()=> Math.max(1, Math.ceil(page.total/page.size)))
const selectedIds = ref([])
const allChecked = ref(false)
const showModal = ref(false)
const editing = ref(false)
const form = reactive({
  id: null,
  customerName: '',
  customerId: null,
  contactPhone: '',
  region: '',
  shippingAddress: '',
  salesRep: '',
  respPhone: '',

  saleDate: '',
  totalAmount: 0,
  expectedShipDate: '',
  remark: '',
  items: [],
  orderDiscount: 0,
  manualTotal: null
})
const showDetail = ref(false)
const current = ref(null)
const detailTab = ref('base')

const showSubmitConfirm = ref(false)
const showSuccess = ref(false)
const successMessage = ref('')
const showPrintPreview = ref(false)
const printPreviewData = ref([])
const isPrinting = ref(false)
function onSubmitConfirm(){ showSubmitConfirm.value = true }

function statusText(s){
  const statusMap = { 0: '未提交', 1: '审核中', 2: '已完成', 3: '审核拒绝' }
  return statusMap[s] || '未知状态'
}
function getStatusClass(s) { const classMap = { 0: 'pending', 1: 'reviewing', 2: 'completed', 3: 'rejected' }; return classMap[s] || 'unknown' }
function formatDate(d){ return d? new Date(d).toLocaleDateString() : '-' }
function formatAmount(amount) { return amount!=null ? `¥${Number(amount||0).toFixed(2)}` : '¥0.00' }

async function load(){
  const res = await getOrderPage({ pageNo: page.current, pageSize: page.size, ...query })
  const data = res.data ?? res
  list.value = data.records || []
  page.total = data.total || 0
  page.current = data.current || 1
  page.size = data.size || 10
  // 若后端已返回 customerName，则无需额外请求；否则再按ID补齐
  const needFetch = list.value.filter(i=>!i.customerName && i.customerId)
  if(needFetch.length){
    const ids = [...new Set(needFetch.map(i=>i.customerId).filter(Boolean))]
  customerMap.value = {}
  for(const id of ids){
    try{ const r = await getCustomerDetail(id); const c = r.data || r; customerMap.value[id] = c.customerName || c.customer_name || id }catch(e){ customerMap.value[id] = id }
  }
}
}

function onSearch(){ 
  page.current = 1; 
  load()
  successMessage.value = '搜索完成'
  showSuccess.value = true
}
function reset(){ 
  Object.assign(query,{ customerName: '', soCode: '', status: '', startDate: '', endDate: '' }); 
  onSearch()
  successMessage.value = '筛选条件已重置'
  showSuccess.value = true
}
function go(p){ 
  page.current=p; 
  load()
  successMessage.value = `已跳转到第 ${p} 页`
  showSuccess.value = true
}
function toggleAll(){ 
  allChecked.value ? selectedIds.value = list.value.map(i=>i.id) : selectedIds.value = []
  successMessage.value = allChecked.value ? `已全选 ${list.value.length} 条记录` : '已取消全选'
  showSuccess.value = true
}

const sortState = reactive({ field:'createdAt', asc:false })
const listSorted = computed(()=>{
  const arr = [...list.value]
  const f = sortState.field
  arr.sort((a,b)=>{ const va = a[f]; const vb = b[f]; if(va===vb) return 0; return (va>vb?1:-1)*(sortState.asc?1:-1) })
  return arr
})
function sortBy(field){ if(sortState.field===field){ sortState.asc=!sortState.asc } else { sortState.field=field; sortState.asc=true } }
function sortIcon(field){ return sortState.field!==field? 'sort': (sortState.asc? 'sort-asc':'sort-desc') }

function openAdd(){
  editing.value=false;
  Object.assign(form,{ id:null, customerName:'', customerId:null, contactPhone:'', region:'', shippingAddress:'', salesRep:'', respPhone:'', saleDate:'', totalAmount:0, expectedShipDate:'', remark:'', items:[], orderDiscount:0, manualTotal:null });
  showModal.value=true
  customerSearchKeyword.value = ''
  loadCustomerSelect()
}
function edit(row){
  editing.value=true;
  Object.assign(form,{ id: row.id, customerName: row.customerName || customerName(row.customerId), customerId: row.customerId || null, contactPhone: row.contactPhone || '', region: row.region || '', shippingAddress: row.shippingAddress || '', salesRep: row.salesRep || '', respPhone: row.respPhone || '', saleDate: (row.saleDate||'').slice(0,10), totalAmount: row.totalAmount || 0, expectedShipDate: (row.expectedShipDate||'').slice(0,10), remark: row.remark || '', items: row.items || [], orderDiscount: row.orderDiscount || 0, manualTotal: row.manualTotal ?? null });
  showModal.value=true
  customerSearchKeyword.value = ''
  loadCustomerSelect()
}

async function save(){
  if(!form.customerId){
    return alert('请选择客户（下拉选择后会绑定客户ID）')
  }
  // 若缺少 customerId，依据名称尝试查询匹配
  if(!form.customerId && form.customerName){
    try{
      const r = await getCustomerPage({ pageNo:1, pageSize:1, customerName: form.customerName })
      const d = r.data || r
      const first = (d.records && d.records[0]) || null
      if(first && (first.id || first.customerId)) form.customerId = first.id || first.customerId
    }catch(e){ /* ignore，保持为空由后端校验 */ }
  }
  // 后端SalesOrderDTO结构：{ order: SalesOrder, items: SalesOrderItem[] , totalAmount }
  const order = {
    id: form.id || undefined,
    soCode: undefined, // 由后端生成
    customerId: form.customerId || undefined,

    currency: 'CNY', // 默认币种
    taxIncluded: 'Y', // 默认含税
    // 新增业务字段
    contactPhone: form.contactPhone || '',
    region: form.region || '',
    shippingAddress: form.shippingAddress || '',
    salesRep: form.salesRep || '',
    respPhone: form.respPhone || '',
    saleDate: form.saleDate || null,
    expectedShipDate: form.expectedShipDate || null,
    remark: form.remark || '',
    status: undefined
  }
  const items = (form.items||[]).map((it,idx)=>({
    lineNo: idx+1,
    skuId: it.skuId,
    productId: it.productId, // 添加productId用于后端处理临时SKU
    qty: Number(it.qty||0),
    price: Number(it.price||0),
    taxRate: Number(it.taxRate||0),
    amount: undefined
  }))
  const payload = { order, items, totalAmount: Number(orderAmount.value||0) }
  console.log('保存订单数据:', payload) // 添加调试日志
  let res
  if(editing.value){ res = await updateFullOrder(form.id, payload) } else { res = await createFullOrder(payload) }
  if(res && (res.success===true || res.code===0 || res.code===200)){ 
    showModal.value=false; 
    successMessage.value = editing.value ? '销售订单更新成功' : '销售订单创建成功'
    showSuccess.value = true
    load() 
  } else { alert(res?.message || '保存失败') }
}
function close(){ 
  showModal.value=false 
  customerSearchKeyword.value = ''
}

async function delOne(row){ 
  if(row.status!==0) return alert('仅未提交可删除'); 
  if(!confirm('确认删除该销售订单吗？')) return; 
  const r = await deleteOrderBatch([row.id]); 
  if(r.success){ 
    successMessage.value = '销售订单删除成功'
    showSuccess.value = true
    load() 
  } else alert(r.message) 
}
async function batchDelete(){ 
  if(selectedIds.value.length===0) return; 
  if(!confirm(`删除 ${selectedIds.value.length} 个未提交销售订单？`)) return; 
  const r = await deleteOrderBatch(selectedIds.value); 
  if(r.success){ 
    successMessage.value = `批量删除成功（${selectedIds.value.length} 条）`
    showSuccess.value = true
    selectedIds.value=[]; 
    allChecked.value=false; 
    load() 
  } else alert(r.message) 
}
// 删除顶部示例详情入口，保留行内详情按钮
function selectOne(id){ selectedIds.value = [id]; allChecked.value=false }

async function openRowDetail(row){
  try{
    const r = await getFullOrderDetail(row.id)
    current.value = r.data || r
  }catch(e){
    // 若后端未就绪，回退到本地示例，避免空白
    const merged = { ...mockDetail, soCode: row.soCode || mockDetail.soCode, totalAmount: row.totalAmount ?? mockDetail.totalAmount, createdAt: row.createdAt || mockDetail.createdAt, status: row.status ?? mockDetail.status, customerName: customerName(row.customerId) || mockDetail.customerName }
    current.value = merged
  }
  detailTab.value='base'
  showDetail.value = true
}
function submitForReview(){ 
  showSubmitConfirm.value=false; 
  if(selectedIds.value.length === 0) { 
    alert('请选择要提交审核的订单'); 
    return 
  } 
  successMessage.value = `已提交 ${selectedIds.value.length} 个订单进行审核`
  showSuccess.value = true
}
async function printOrders(){ 
  if(selectedIds.value.length === 0) { 
    alert('请选择要打印的订单'); 
    return 
  } 
  
  // 显示打印预览
  printPreviewData.value = list.value.filter(item => selectedIds.value.includes(item.id))
  showPrintPreview.value = true
}

// 智能打印：勾选一个框是单个打印，多个是批量打印
async function smartPrint() {
  if (selectedIds.value.length === 0) {
    alert('请选择要打印的订单');
    return;
  }
  
  try {
    // 设置打印状态
    isPrinting.value = true;
    
    if (selectedIds.value.length === 1) {
      // 单个订单打印
      const orderId = selectedIds.value[0];
      const order = list.value.find(item => item.id === orderId);
      
      if (!order) {
        throw new Error('订单不存在');
      }
      
      // 显示打印中提示
      successMessage.value = `正在生成订单 ${order.soCode || order.id} 的打印文件...`;
      showSuccess.value = true;
      
      // 调用单个订单打印API
      const response = await getOrderPrintData(orderId);
      
      // 处理返回的PDF文件
      if (response && response.data) {
        const blob = new Blob([response.data], { type: 'application/pdf' });
        const url = window.URL.createObjectURL(blob);
        
        // 创建下载链接
        const link = document.createElement('a');
        link.href = url;
        link.download = `销售订单_${order.soCode || order.id}_${new Date().toISOString().slice(0, 10)}.pdf`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        
        // 释放URL对象
        window.URL.revokeObjectURL(url);
        
        successMessage.value = `订单 ${order.soCode || order.id} 打印文件已生成`;
        showSuccess.value = true;
      } else {
        throw new Error('打印文件生成失败');
      }
    } else {
      // 多个订单批量打印
      // 显示打印预览
      printPreviewData.value = list.value.filter(item => selectedIds.value.includes(item.id));
      showPrintPreview.value = true;
    }
  } catch (error) {
    console.error('打印失败:', error);
    alert(`打印失败: ${error.message || '未知错误'}`);
  } finally {
    // 重置打印状态
    isPrinting.value = false;
  }
}

// 确认打印
async function confirmPrint() {
  try {
    // 设置打印状态
    isPrinting.value = true
    
    // 关闭预览弹框
    showPrintPreview.value = false
    
    // 显示打印中提示
    successMessage.value = `正在生成打印文件...`
    showSuccess.value = true
    
    // 调用批量打印API
    const response = await printOrdersBatch(selectedIds.value)
    
    // 处理返回的PDF文件
    if (response && response.data) {
      const blob = new Blob([response.data], { type: 'application/pdf' })
      const url = window.URL.createObjectURL(blob)
      
      // 创建下载链接
      const link = document.createElement('a')
      link.href = url
      link.download = `销售订单_${new Date().toISOString().slice(0, 10)}.pdf`
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      
      // 释放URL对象
      window.URL.revokeObjectURL(url)
      
      successMessage.value = `打印文件已生成，共 ${selectedIds.value.length} 个订单`
      showSuccess.value = true
    } else {
      throw new Error('打印文件生成失败')
    }
  } catch (error) {
    console.error('打印失败:', error)
    alert(`打印失败: ${error.message || '未知错误'}`)
  } finally {
    // 重置打印状态
    isPrinting.value = false
  }
}

// 单个订单打印
async function printSingleOrder(order) {
  try {
    // 设置打印状态
    isPrinting.value = true
    
    // 显示打印中提示
    successMessage.value = `正在生成订单 ${order.soCode || order.id} 的打印文件...`
    showSuccess.value = true
    
    // 调用单个订单打印API
    const response = await getOrderPrintData(order.id)
    
    // 处理返回的PDF文件
    if (response && response.data) {
      const blob = new Blob([response.data], { type: 'application/pdf' })
      const url = window.URL.createObjectURL(blob)
      
      // 创建下载链接
      const link = document.createElement('a')
      link.href = url
      link.download = `销售订单_${order.soCode || order.id}_${new Date().toISOString().slice(0, 10)}.pdf`
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      
      // 释放URL对象
      window.URL.revokeObjectURL(url)
      
      successMessage.value = `订单 ${order.soCode || order.id} 打印文件已生成`
      showSuccess.value = true
    } else {
      throw new Error('打印文件生成失败')
    }
  } catch (error) {
    console.error('打印失败:', error)
    alert(`打印失败: ${error.message || '未知错误'}`)
  } finally {
    // 重置打印状态
    isPrinting.value = false
  }
}

// 商品明细计算
function discountPrice(it){ const price = Number(it.price||0); const discount = Number(it.discount||0); return price * (100 - discount) / 100 }
function lineAmount(it){ const qty = Number(it.qty||0); return qty * discountPrice(it) }
const orderAmount = computed(()=>{
  // 只有当手动总价不为空且不为0时才使用手动总价
  if(form.manualTotal != null && form.manualTotal !== '' && Number(form.manualTotal) > 0) {
    return Number(form.manualTotal)
  }
  const sum = (form.items||[]).reduce((s,it)=> s + lineAmount(it), 0)
  return sum * (100 - Number(form.orderDiscount||0)) / 100
})
function changeQty(idx, delta){ const it = form.items[idx]; it.qty = Math.max(0, Number(it.qty||0) + delta) }
function removeItem(idx){ 
  form.items.splice(idx,1)
  successMessage.value = '商品明细删除成功'
  showSuccess.value = true
}

// 关联商品弹窗数据与逻辑
const showProductPicker = ref(false)
const productKeyword = ref('')
const productCandidates = ref([])
const productLoading = ref(false)
let productLoadTimer = null
const productPage = reactive({ current:1, size:15, total:0 })
async function loadProducts(){
  try{
    productLoading.value = true
    console.log('开始加载商品数据...', { keyword: productKeyword.value, page: productPage.current, size: productPage.size })
    
    // 调用商品服务：支持按关键字(name/code/spec)模糊
    const r = await import('@/api/sales').then(m=> m.getProductOptions({ 
      keyword: productKeyword.value || '', 
      pageNo: productPage.current, 
      pageSize: productPage.size 
    }))
    
    console.log('商品查询响应:', r)
    
    // 处理不同的响应格式
    let data, list, total
    if (r.success !== undefined) {
      // 标准Result格式
      data = r.data
      list = data?.records || data?.list || []
      total = data?.total || 0
    } else if (r.records !== undefined) {
      // 直接分页格式
      list = r.records || r.list || []
      total = r.total || 0
    } else {
      // 其他格式
      list = r.data?.records || r.data?.list || r.records || r.list || []
      total = r.data?.total || r.total || 0
    }
    
    productPage.total = total
    productCandidates.value = list.map(it=>({
      // 商品服务返回 Product：id, productName, spuCode, barCode, retailPrice, categoryName...
      productId: it.id,
      skuId: it.id, // 暂时使用商品ID作为SKU ID
      code: it.spuCode || it.barCode || it.spu_code || it.bar_code || '',
      name: it.productName || it.name || it.product_name || '',
      spec: it.unitName || it.categoryName || it.unit_name || it.category_name || it.barCode || it.bar_code || '标准规格',
      unit: it.unitName || it.unit_name || '件',
      price: Number(it.retailPrice || it.standardCost || it.retail_price || it.standard_cost || 0)
    }))
    
    console.log('处理后的商品数据:', productCandidates.value)
  }catch(e){ 
    console.error('加载商品失败:', e)
    productCandidates.value = [] 
  } finally {
    productLoading.value = false
  }
}
const pickedProducts = ref([])
const leftSelected = ref([]); const rightSelected = ref([])
const leftAllChecked = ref(false); const rightAllChecked = ref(false)
const filteredCandidates = computed(()=>{
  return productCandidates.value
})
function openProductPicker(){
  console.log('打开商品选择器')
  
  // 初始化右侧为当前已选（根据 skuId 去重）
  pickedProducts.value = (form.items||[]).map(i=> ({ 
    skuId:i.skuId, 
    productId: i.productId,
    code:i.skuId, 
    name:i.name, 
    spec:i.spec, 
    unit:i.unit, 
    price:i.price 
  }))
  
  leftSelected.value = []; 
  rightSelected.value = []; 
  leftAllChecked.value=false; 
  rightAllChecked.value=false
  
  showProductPicker.value = true
  
  // 重置搜索关键词和分页
  productKeyword.value = ''
  productPage.current = 1
  
  // 加载商品数据
  loadProducts()
}
function closeProductPicker(){ showProductPicker.value=false }
function toggleLeftAll(){ leftSelected.value = leftAllChecked.value ? filteredCandidates.value.map(i=>i.skuId) : [] }
function toggleRightAll(){ rightSelected.value = rightAllChecked.value ? pickedProducts.value.map(i=>i.skuId) : [] }
function moveToRight(){ const set = new Set(pickedProducts.value.map(i=>i.skuId)); for(const id of leftSelected.value){ const p = productCandidates.value.find(i=>i.skuId===id); if(p && !set.has(id)) pickedProducts.value.push({ ...p }) } leftSelected.value=[]; leftAllChecked.value=false }
function moveToLeft(){ pickedProducts.value = pickedProducts.value.filter(i=> !rightSelected.value.includes(i.skuId)); rightSelected.value=[]; rightAllChecked.value=false }
async function confirmPick(){
  // 将右侧已选写入 form.items（若已存在则不重复，只更新名称/规格/单价）
  const map = new Map(form.items.map(i=>[i.skuId,i]))
  for(const p of pickedProducts.value){
    let skuId = p.skuId
    if(!skuId && p.productId){
      try{
        const r = await getSkuPage({ productId: p.productId, pageNo:1, pageSize:1 })
        const d = r.data || r
        const first = d.records && d.records[0]
        skuId = first?.id
      }catch(e){ skuId = null }
    }
    if(!skuId){ alert(`商品 ${p.name} 缺少SKU，无法添加`); continue }
    if(map.has(p.skuId)){
      const it = map.get(p.skuId); Object.assign(it,{ name:p.name, spec:p.spec, unit:p.unit, price:p.price })
    }else{
      form.items.push({ 
        skuId: skuId, 
        productId: p.productId, // 保留productId用于后端处理
        name: p.name, 
        spec: p.spec, 
        unit: p.unit, 
        qty: 1, // 默认数量为1
        price: p.price || 0, 
        discount: 0 
      })
    }
  }
  showProductPicker.value=false
  successMessage.value = '商品选择完成'
  showSuccess.value = true
}

// 直接添加某个候选商品到明细
async function addCandidate(p){
  let skuId = p.skuId
  if(!skuId && p.productId){
    try{
      const r = await getSkuPage({ productId: p.productId, pageNo:1, pageSize:1 })
      const d = r.data || r
      const first = d.records && d.records[0]
      skuId = first?.id
    }catch(e){ skuId = null }
  }
  // 如果没有SKU，使用productId作为临时标识，后端会处理
  if(!skuId && p.productId){
    skuId = `temp_${p.productId}`
  }
  if(!skuId){ 
    alert('该商品缺少SKU，无法添加'); 
    return 
  }
  const exists = form.items.find(i=> i.skuId===skuId)
  if(!exists){
    form.items.push({ 
      skuId: skuId, 
      productId: p.productId, // 保留productId用于后端处理临时SKU
      name: p.name, 
      spec: p.spec, 
      unit: p.unit, 
      qty: 1, // 默认数量为1
      price: p.price || 0, 
      discount: 0,
      taxRate: 0 // 添加税率字段
    })
    console.log('添加商品到订单:', p.name, 'SKU:', skuId, 'ProductID:', p.productId) // 添加调试日志
    successMessage.value = '商品添加成功'
    showSuccess.value = true
  }
}

// 关键字变化防抖加载
watch(productKeyword, (v)=>{
  clearTimeout(productLoadTimer)
  productLoadTimer = setTimeout(()=>{ 
    productPage.current=1; 
    loadProducts() 
  }, 500)
})

// 客户名映射
const customerMap = ref({})
const customerName = (id)=> customerMap.value[id] || id
const rowClass = (o)=> ({ grey: o.status===0, red: o.status===3, green: o.status===2, blue: o.status===1 })

// 客户下拉（纯下拉）
const customerSelectOptions = ref([])
const customerSearchKeyword = ref('')
const filteredCustomerOptions = ref([])

// 格式化客户显示名称
function formatCustomerDisplay(customer) {
  if (!customer) return '未知客户'
  
  const name = customer.customerName || customer.contactName || customer.name
  const code = customer.customerCode || customer.customer_code
  const phone = customer.phone || customer.contactPhone
  
  if (name && code) {
    return `${name} (${code})`
  } else if (name && phone) {
    return `${name} - ${phone}`
  } else if (name) {
    return name
  } else if (code) {
    return `客户${code}`
  } else {
    return `客户${customer.id}`
  }
}

// 过滤客户选项
function filterCustomers() {
  const keyword = customerSearchKeyword.value.toLowerCase().trim()
  if (!keyword) {
    filteredCustomerOptions.value = customerSelectOptions.value
    return
  }
  
  filteredCustomerOptions.value = customerSelectOptions.value.filter(customer => {
    const name = (customer.customerName || customer.contactName || customer.name || '').toLowerCase()
    const code = (customer.customerCode || customer.customer_code || '').toLowerCase()
    const phone = (customer.phone || customer.contactPhone || '').toLowerCase()
    
    return name.includes(keyword) || code.includes(keyword) || phone.includes(keyword)
  })
}
async function loadCustomerSelect(){
  try{
    console.log('开始加载客户下拉选项...')
    const r = await getCustomerPage({ pageNo:1, pageSize:200 })
    console.log('客户接口返回:', r)
    const d = r.data || r
    customerSelectOptions.value = d.records || d.list || []
    console.log('客户选项:', customerSelectOptions.value)
    
    // 初始化过滤后的选项
    filteredCustomerOptions.value = customerSelectOptions.value
    customerSearchKeyword.value = ''
  }catch(e){ 
    console.error('加载客户失败:', e)
    customerSelectOptions.value = []
    filteredCustomerOptions.value = []
  }
}
async function onCustomerChange(){
  const sel = customerSelectOptions.value.find(c=> (c.id || c.customerId) === form.customerId)
  if(sel){ 
    form.customerName = sel.customerName || sel.contactName || sel.name
    form.contactPhone = sel.phone || sel.contactPhone || ''
    form.region = sel.region || ''
    form.shippingAddress = sel.shippingAddress || sel.address || ''
  }
  // 进一步获取详情以回填更多字段
  if(form.customerId){
    try{
      const r = await getCustomerDetail(form.customerId)
      const c = r.data || r
      // 根据后端返回的字段尽可能回填
      form.customerName = c.customerName || sel?.customerName || sel?.contactName || form.customerName
      form.contactPhone = c.phone || c.contactPhone || sel?.phone || form.contactPhone
      form.region = c.region || sel?.region || form.region
      form.shippingAddress = c.shippingAddress || c.address || sel?.shippingAddress || sel?.address || form.shippingAddress
      // 价格表ID若存在则带入
  
      // 保持销售负责人和负责人电话不变，除非客户信息中有相关字段
      if(c.salesRep) form.salesRep = c.salesRep
      if(c.respPhone) form.respPhone = c.respPhone
    }catch(e){
      console.error('获取客户详情失败:', e)
    }
  }
}

// 详情页模拟数据（审批/出库/回款/退货）
const mockApprovals = [
  { title:'发起申请', status:'wait', user:'夏油杰', dept:'销售部', role:'采购专员', date:'2024-06-09', remark:'发起采购申请' },
  { title:'审批拒绝', status:'reject', user:'夏油杰', dept:'销售部', role:'采购主管', date:'2024-06-09' },
  { title:'审批通过', status:'pass', user:'夏油杰', dept:'销售部', role:'采购主管', date:'2024-06-09' },
  { title:'审批通过', status:'pass', user:'夏油杰', dept:'销售部', role:'财务专员', date:'2024-06-09' },
  { title:'审批通过', status:'pass', user:'夏油杰', dept:'销售部', role:'财务总监', date:'2024-06-09' },
  { title:'审批中', status:'wait', user:'夏油杰', dept:'销售部', role:'出纳', date:'2024-06-09' }
]
const mockStocks = [
  { name:'农夫果园', spec:'24*550ml/瓶', unit:'箱', status:'all', statusText:'全部入库', qty:200, inQty:200, waitQty:0, billNo:'RK00001', user:'夏油杰', time:'2024/05/23 12:25:32' },
  { name:'农夫果园', spec:'24*550ml/瓶', unit:'箱', status:'wait', statusText:'待入库', qty:200, inQty:0, waitQty:200, billNo:'RK00001', user:'夏油杰', time:'2024/05/23 12:25:32' }
]
const mockPayments = [
  { no:'FK0001', amount:1200, method:'支付宝', time:'2024/12/23 12:12:23', approver:'夏油杰', creator:'夏油杰', createTime:'2024/05/23 12:25:32' },
  { no:'FK0001', amount:1200, method:'微信', time:'2024/12/23 12:12:23', approver:'夏油杰', creator:'夏油杰', createTime:'2024/05/23 12:25:32' }
]
const mockReturns = [
  { no:'FK0001', amount:1200, method:'支付宝', time:'2024/12/23 12:12:23', approver:'夏油杰', creator:'夏油杰', createTime:'2024/05/23 12:25:32' },
  { no:'FK0001', amount:1200, method:'微信', time:'2024/12/23 12:12:23', approver:'夏油杰', creator:'夏油杰', createTime:'2024/05/23 12:25:32' }
]

const mockDetail = {
  soCode: 'SH00001',
  purchaseAmount: 2333333,
  totalAmount: 6552.76,
  createdAt: '2024-08-09T12:00:00Z',
  expectedShipDate: '2024-08-12T00:00:00Z',
  status: 2,
  remark: '———',
  customerName: '夏油杰',
  contactPhone: '13398788875',
  region: '江苏省',
  shippingAddress: '南京市雨花区XXX街道XXX小区XXX号',
  salesRep: '夏油杰',
  respPhone: '13333333333',
  creator: '夏油杰',
  updater: '夏油杰',
  updatedAt: '2024-09-12T00:00:00Z',
  items: [
    { skuId:'S000012', name:'衬衫', spec:'S000012', qty:12, price:100, discount:1 },
    { skuId:'S000012', name:'衬衫', spec:'S000012', qty:12, price:100, discount:1 },
    { skuId:'S000012', name:'衬衫', spec:'S000012', qty:12, price:100, discount:1 }
  ],
  approvals: mockApprovals,
  stocks: [
    { name:'农夫果园', spec:'24*550ml/瓶', unit:'箱', status:'all', statusText:'全部入库', qty:200, inQty:200, waitQty:0, billNo:'RK00001', user:'夏油杰', time:'2024/05/23 12:25:32' },
    { name:'农夫果园', spec:'24*550ml/瓶', unit:'箱', status:'part', statusText:'部分入库', qty:200, inQty:100, waitQty:100, billNo:'RK00001', user:'夏油杰', time:'2024/05/23 12:25:32' }
  ],
  payments: mockPayments,
  returns: mockReturns
}

onMounted(load)

const pretty = (v)=> JSON.stringify(v, null, 2)
</script>

<style scoped>
.customer-select-wrapper {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.customer-select-wrapper input {
  margin-bottom: 6px;
  height: 36px;
  padding: 8px 12px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  background: #fff;
  font-size: 13px;
  transition: all .2s ease;
}

.customer-select-wrapper input:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 2px rgba(59,130,246,.1);
}

.customer-select-wrapper select {
  width: 100%;
  height: 42px;
  padding: 10px 14px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #fff;
  color: #374151;
  font-size: 14px;
  transition: all .2s ease;
}

.customer-select-wrapper select:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59,130,246,.1);
}
.page{ display:flex; flex-direction:column; gap:16px; background:#f6f7f9; min-height:100%; padding:12px }
.page-header{ display:flex; justify-content:space-between; align-items:center; background:#fff; padding:12px 16px; border-radius:12px; box-shadow:0 8px 24px rgba(36,46,66,.06) }
.actions{ display:flex; gap:10px }
.search{ display:flex; gap:10px; align-items:center; background:#fff; padding:14px; border-radius:12px; box-shadow:0 8px 24px rgba(36,46,66,.06); flex-wrap: wrap; }
.ipt{ padding:10px 12px; border:1px solid #dde2eb; border-radius:10px; min-width: 140px; transition:border .2s, box-shadow .2s; background:#fff }
.ipt:focus{ outline:none; border-color:#8cb4ff; box-shadow:0 0 0 3px rgba(22,119,255,.15) }
.ipt-sm{ padding:6px 8px; width:90px }
.date-range{ display: flex; align-items: center; gap: 8px; }
.date-separator{ color: #666; font-size: 14px; }
.btn{ 
  padding:12px 20px; 
  border:1px solid #d1d5db; 
  background:#fff; 
  border-radius:8px; 
  cursor:pointer; 
  transition:all .2s ease; 
  color:#374151;
  font-size: 14px;
  font-weight: 500;
  box-shadow: 0 1px 2px rgba(0,0,0,.05);
}
.btn:hover{ 
  transform:translateY(-1px); 
  box-shadow:0 4px 8px rgba(0,0,0,.1);
  border-color: #9ca3af;
}
.btn:disabled{ 
  opacity:.5; 
  cursor:not-allowed; 
  box-shadow:none; 
  transform:none;
  background: #f3f4f6;
  color: #9ca3af;
}
.btn-primary{ 
  background:#3b82f6; 
  color:#fff; 
  border-color:#3b82f6;
  box-shadow: 0 1px 3px rgba(59,130,246,.3);
}
.btn-primary:hover{ 
  background:#2563eb; 
  border-color:#2563eb;
  box-shadow: 0 4px 8px rgba(59,130,246,.4);
}
.btn.danger{ 
  background:#ef4444; 
  color:#fff; 
  border-color:#ef4444;
  box-shadow: 0 1px 3px rgba(239,68,68,.3);
}
.btn.danger:hover{ 
  background:#dc2626; 
  border-color:#dc2626;
  box-shadow: 0 4px 8px rgba(239,68,68,.4);
}
.btn.sm{ 
  padding:6px 12px; 
  font-size:12px; 
  border-radius:6px;
  height: 28px;
  line-height: 1;
}
.table-wrap{ background:#fff; border-radius:12px; padding:12px; box-shadow:0 8px 24px rgba(36,46,66,.06) }
table{ width:100%; border-collapse:collapse }
th{ padding:12px 10px; background:#eef3ff; color:#2b3a55; font-weight:600; border-bottom:1px solid #e9edf5; text-align:left }
td{ padding:12px 10px; border-bottom:1px solid #f0f3f8; text-align:left; color:#344767 }
/* 金额与数量列右对齐 */
td.num, th.num{ text-align:right }
tbody tr:hover{ background:#fafcff }
.pager{ display:flex; gap:10px; justify-content:flex-end; padding-top:10px }
.modal{ 
  position:fixed; 
  inset:0; 
  background:rgba(0,0,0,.6); 
  display:flex; 
  align-items:center; 
  justify-content:center; 
  backdrop-filter: blur(4px);
  z-index: 1000;
  animation: fadeIn 0.3s ease-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.dialog-fixed {
  animation: slideIn 0.3s ease-out;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(-20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
.dialog{ 
  width:760px; 
  background:#fff; 
  border-radius:16px; 
  padding:20px; 
  box-shadow: 0 20px 60px rgba(0,0,0,.3);
}
.dialog-fixed{ 
  width:1200px; 
  max-width: 95vw;
  max-height:90vh; 
  overflow:auto; 
  border-radius:16px; 
  box-shadow:0 20px 60px rgba(0,0,0,.3);
  background: #fff;
  padding: 24px;
  /* 自定义滚动条 */
  scrollbar-width: thin;
  scrollbar-color: #d1d5db #f9fafb;
}

.dialog-fixed::-webkit-scrollbar {
  width: 8px;
}

.dialog-fixed::-webkit-scrollbar-track {
  background: #f9fafb;
  border-radius: 4px;
}

.dialog-fixed::-webkit-scrollbar-thumb {
  background: #d1d5db;
  border-radius: 4px;
}

.dialog-fixed::-webkit-scrollbar-thumb:hover {
  background: #9ca3af;
}

/* 弹框标题美化 */
.dialog h3 {
  margin: 0 0 20px;
  font-size: 20px;
  font-weight: 700;
  color: #1f2937;
  padding-bottom: 12px;
  border-bottom: 2px solid #f3f4f6;
}

/* 表单更精致的布局与控件样式（两列左对齐） */
.form-grid{ 
  display:grid; 
  grid-template-columns:1fr 1fr; 
  column-gap:24px; 
  row-gap:16px; 
  margin-top:16px;
  padding: 20px;
  background: #fafbfc;
  border-radius: 12px;
  border: 1px solid #e5e7eb;
}
.form-grid label{ 
  display:flex; 
  flex-direction:column; 
  gap:8px; 
  font-weight:600; 
  color:#374151;
  font-size: 14px;
}
.form-grid input, .form-grid select{ 
  width:100%; 
  height:42px; 
  padding:10px 14px; 
  border:1px solid #d1d5db; 
  border-radius:8px; 
  background:#fff; 
  color:#374151; 
  transition:all .2s ease; 
  min-width:260px;
  font-size: 14px;
}
.form-grid input::placeholder{ 
  color:#9ca3af;
  font-size: 14px;
}
.form-grid input:focus, .form-grid select:focus{ 
  outline:none; 
  border-color:#3b82f6; 
  box-shadow:0 0 0 3px rgba(59,130,246,.1);
  background: #fff;
}
.form-grid input:hover, .form-grid select:hover {
  border-color: #9ca3af;
}
.form-grid .col-2{ grid-column: span 2 }
.section{ 
  margin-top:24px; 
  border-top:2px solid #f3f4f6; 
  padding-top:20px;
  background: #fafbfc;
  border-radius: 12px;
  padding: 20px;
  border: 1px solid #e5e7eb;
}
.section-header{ 
  display:flex; 
  justify-content:space-between; 
  align-items:center; 
  margin-bottom:16px; 
  font-weight:700; 
  color:#1f2937;
  font-size: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid #e5e7eb;
}

.qty{ 
  display:flex; 
  align-items:center; 
  gap:8px;
}

/* 表格美化 */
.section table {
  width: 100%;
  border-collapse: collapse;
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,.1);
  margin-top: 12px;
}

.section table thead {
  background: #f8fafc;
}

.section table th {
  padding: 12px 8px;
  text-align: left;
  font-weight: 600;
  color: #374151;
  font-size: 13px;
  border-bottom: 1px solid #e5e7eb;
}

.section table td {
  padding: 12px 8px;
  border-bottom: 1px solid #f3f4f6;
  font-size: 13px;
  color: #374151;
}

.section table tbody tr:hover {
  background: #f9fafb;
}

.section table .ipt-sm {
  height: 32px;
  padding: 6px 8px;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  font-size: 12px;
  width: 80px;
}

.section table .ipt-sm:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 2px rgba(59,130,246,.1);
}
.order-summary{ 
  display:grid; 
  grid-template-columns:1fr 1fr 1fr; 
  gap:20px; 
  margin-top:20px;
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  box-shadow: 0 1px 3px rgba(0,0,0,.1);
}
.order-summary .ipt{ 
  min-width:200px;
  height: 42px;
  padding: 10px 14px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #fff;
  color: #374151;
  font-size: 14px;
  transition: all .2s ease;
}
.order-summary .ipt:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59,130,246,.1);
}
.order-summary label {
  font-weight: 600;
  color: #374151;
  font-size: 14px;
  margin-bottom: 6px;
  display: block;
}
.dialog-actions{ 
  display:flex; 
  justify-content:flex-end; 
  gap:16px; 
  margin-top:24px;
  padding-top: 20px;
  border-top: 1px solid #e5e7eb;
}

.detail{ background:#0b1020; color:#9efc9e; padding:12px; border-radius:12px; max-height:60vh; overflow:auto }
.status.pending{ color:#8f9bb3; font-weight:600 }
.status.reviewing{ color:#1677ff; font-weight:600 }
.status.completed{ color:#10b981; font-weight:600 }
.status.rejected{ color:#ff4d4f; font-weight:600 }
.status.unknown{ color:#666; font-weight:600 }
.link{ cursor:pointer; color:#1677ff }
.link.danger{ color:#ff4d4f }

/* 详情样式 */
.detail-header{ display:flex; justify-content:space-between; align-items:center }
.detail-title{ font-size:22px; font-weight:700 }
.summary{ display:grid; grid-template-columns:repeat(6,1fr); gap:12px; background:#f7f9ff; padding:12px; border-radius:12px; margin-top:8px }
.summary .card{ background:#fff; border:1px solid #edf1fa; border-radius:12px; padding:12px; box-shadow:0 4px 14px rgba(36,46,66,.06) }
.summary .label{ color:#6b7485; font-size:12px }
.summary .value{ margin-top:6px; font-weight:700; color:#2b3a55 }
.tabs{ display:flex; gap:12px; border-bottom:1px solid #edf1fa; margin-top:14px }
.tab{ padding:10px 14px; cursor:pointer; border-radius:10px 10px 0 0; font-weight:600; color:#42526e }
.tab.active{ background:#eef3ff; color:#1677ff }
.tab-pane{ padding-top:12px }
.base-grid{ display:grid; grid-template-columns:1fr 1fr; gap:12px }
.base-grid .col-2{ grid-column:span 2 }
.base-grid input{ width:100%; padding:10px 12px; border:1px solid #edf1fa; border-radius:10px; background:#f6f8fc; color:#5b6375 }
.flow-list{ display:flex; flex-direction:column; gap:14px }
.flow-item{ display:grid; grid-template-columns:40px 100px 1fr 1fr 1fr 1fr 2fr; align-items:center; background:#f5f7fb; border-radius:12px; padding:10px }
.flow-icon{ width:32px; height:32px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-weight:700; color:#fff }
.flow-icon.ok{ background:#22c55e }
.flow-icon.no{ background:#ef4444 }
.flow-icon.wait{ background:#f59e0b }
.flow-chip{ padding:6px 10px; border-radius:20px; color:#fff; text-align:center }
.flow-chip.pass{ background:#22c55e }
.flow-chip.reject{ background:#ef4444 }
.flow-chip.wait{ background:#f59e0b }
.stock-actions{ display:flex; align-items:center; gap:8px; margin-bottom:8px }
.table-wrap-in{ background:#fff; padding:8px; border-radius:12px }
.badge.all{ color:#10b981; font-weight:700 }
.badge.wait{ color:#f59e0b; font-weight:700 }
.green{ color:#10b981 }

/* 选择商品弹窗分页 */
.picker{ 
  display:flex; 
  gap:20px; 
  margin:20px 0; 
  min-height: 400px;
}
.picker-pane{ 
  flex:1; 
  background:#f8f9fa; 
  border:1px solid #e5e7eb; 
  border-radius:12px; 
  padding:16px; 
  overflow:auto; 
  max-height:60vh;
  display: flex;
  flex-direction: column;
}
.picker-search{ 
  padding-bottom:16px;
  margin-bottom: 16px;
  border-bottom: 1px solid #e5e7eb;
}
.picker-search .ipt {
  width: 100%;
  padding: 12px 16px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  font-size: 14px;
  transition: all .2s ease;
}
.picker-search .ipt:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59,130,246,.1);
}
.picker-pane table {
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,.1);
  flex: 1;
}
.picker-pane table thead {
  background: #f8fafc;
}
.picker-pane table th {
  padding: 12px 8px;
  text-align: left;
  font-weight: 600;
  color: #374151;
  font-size: 13px;
  border-bottom: 1px solid #e5e7eb;
}
.picker-pane table td {
  padding: 12px 8px;
  border-bottom: 1px solid #f3f4f6;
  font-size: 13px;
  color: #374151;
}
.picker-pane table tbody tr:hover {
  background: #f9fafb;
}
.picker-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  justify-content: center;
  padding: 0 10px;
}
.picker-actions .btn.circle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: bold;
  transition: all .2s ease;
}
.picker-actions .btn.circle:hover {
  transform: scale(1.1);
}
.picker-pager {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 0;
  justify-content: center;
  background: #fff;
  border-radius: 8px;
  margin-top: 12px;
  border: 1px solid #e5e7eb;
}
.circle{ 
  border-radius:999px; 
  width:44px; 
  height:44px;
}

/* 下拉选择样式 */
.dropdown{ position:absolute; top:40px; left:0; right:0; background:#fff; border:1px solid #e6eaf2; border-radius:8px; box-shadow:0 8px 24px rgba(36,46,66,.08); max-height:240px; overflow:auto; z-index:20 }
.dropdown-item{ padding:8px 10px; cursor:pointer }
.dropdown-item:hover{ background:#f5f7fb }

/* 商品选择弹窗优化 */
.product-picker-dialog {
  width: 1200px !important;
  max-width: 95vw;
}

.picker {
  display: flex;
  gap: 20px;
  margin: 20px 0;
  min-height: 400px;
}

.picker-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
}

.picker-search {
  margin-bottom: 16px;
}

.picker-search .ipt {
  width: 100%;
  padding: 12px;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 14px;
}

.picker-pane table {
  flex: 1;
  background: white;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.picker-pane th {
  background: #f1f3f4;
  padding: 12px 8px;
  font-weight: 600;
  color: #333;
  border-bottom: 1px solid #e0e0e0;
}

.picker-pane td {
  padding: 12px 8px;
  border-bottom: 1px solid #f0f0f0;
}

.picker-pane tbody tr:hover {
  background: #f8f9fa;
}

.picker-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  justify-content: center;
  padding: 0 16px;
}

.picker-actions .btn.circle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: bold;
}

.picker-pager {
  margin-top: 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  justify-content: center;
  padding: 12px;
  background: white;
  border-radius: 6px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.1);
}

/* 主页面布局优化 */
.page {
  padding: 20px;
  gap: 20px;
}

.page-header {
  padding: 20px 24px;
  margin-bottom: 8px;
}

.search {
  padding: 20px;
  gap: 16px;
  margin-bottom: 8px;
}

.table-wrap {
  padding: 20px;
}

/* 表单布局优化 */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  margin-bottom: 24px;
}

.form-grid label {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.form-grid input,
.form-grid select {
  padding: 12px;
  border: 1px solid #ddd;
  border-radius: 8px;
  font-size: 14px;
  transition: all 0.2s;
}

.form-grid input:focus,
.form-grid select:focus {
  border-color: #1677ff;
  box-shadow: 0 0 0 2px rgba(22, 119, 255, 0.1);
}

/* 表格优化 */
.table-wrap table {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}

.table-wrap th {
  padding: 16px 12px;
  background: #f8f9fa;
  font-weight: 600;
  color: #333;
  border-bottom: 2px solid #e9ecef;
}

.table-wrap td {
  padding: 16px 12px;
  border-bottom: 1px solid #f0f0f0;
}

.table-wrap tbody tr:hover {
  background: #f8f9fa;
}

/* 按钮优化 */
.btn {
  padding: 12px 16px;
  border-radius: 8px;
  font-weight: 500;
  transition: all 0.2s;
}

.btn-sm {
  padding: 8px 12px;
  font-size: 13px;
}

.btn-primary {
  background: linear-gradient(135deg, #1677ff, #0958d9);
  border: none;
  color: white;
  box-shadow: 0 2px 8px rgba(22, 119, 255, 0.3);
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(22, 119, 255, 0.4);
}

/* 打印按钮样式 */
.btn-print {
  background: linear-gradient(135deg, #10b981, #059669);
  border: none;
  color: white;
  box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);
}

.btn-print:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
  background: linear-gradient(135deg, #34d399, #10b981);
}

/* 打印预览弹框样式 */
.print-preview {
  width: 500px;
  background: #fff;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 10px 24px rgba(0,0,0,.16);
}

/* 加载状态样式 */
.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none !important;
}

.btn:disabled:hover {
  transform: none !important;
  box-shadow: none !important;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #e5e7eb;
}

.preview-header h3 {
  margin: 0;
  font-size: 18px;
  color: #111827;
}

.preview-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.preview-info {
  background: #f9fafb;
  padding: 15px;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
}

.preview-info p {
  margin: 8px 0;
  color: #374151;
  font-size: 14px;
}

.preview-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* 数量输入框优化 */
.qty {
  display: flex;
  align-items: center;
  gap: 8px;
}

.qty .ipt-sm {
  width: 60px;
  text-align: center;
}

/* 表格内输入框优化 */
.table-wrap-in {
  background: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.table-wrap-in table {
  margin: 0;
}

/* 状态样式优化 */
.status {
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.status.wait { background: #fff7e6; color: #d46b08; }
.status.pass { background: #f6ffed; color: #389e0d; }
.status.reject { background: #fff2f0; color: #cf1322; }

/* 链接样式 */
.link {
  color: #1677ff;
  text-decoration: none;
  cursor: pointer;
}

.link:hover {
  text-decoration: underline;
}

.link.danger {
  color: #ff4d4f;
}

/* 模态框优化 */
.dialog {
  max-height: 90vh;
  overflow-y: auto;
}

.dialog-xl {
  width: 1200px;
  max-width: 95vw;
}

/* 成功提示弹框样式 */
.success {
  width: 380px;
  background: #fff;
  border-radius: 12px;
  padding: 18px;
  box-shadow: 0 10px 24px rgba(0,0,0,.16);
  text-align: center;
}

.success h3 {
  margin: 0 0 8px;
  font-size: 18px;
  color: #10b981;
}

.success p {
  color: #4b5563;
  margin: 0 0 14px;
}

.confirm-actions {
  display: flex;
  justify-content: center;
  gap: 10px;
}

/* 加载动画 */
.loading-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid #f3f4f6;
  border-top: 2px solid #3b82f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 响应式优化 */
@media (max-width: 768px) {
  .dialog-fixed {
    width: 95vw;
    padding: 16px;
  }
  
  .form-grid {
    grid-template-columns: 1fr;
    padding: 16px;
    column-gap: 16px;
    row-gap: 12px;
  }
  
  .order-summary {
    grid-template-columns: 1fr;
    gap: 16px;
    padding: 16px;
  }
  
  .section {
    padding: 16px;
  }
  
  .section table {
    font-size: 12px;
  }
  
  .section table th,
  .section table td {
    padding: 8px 4px;
  }
  
  .picker {
    flex-direction: column;
  }
  
  .picker-actions {
    flex-direction: row;
    justify-content: center;
  }
  
  .dialog-actions {
    flex-direction: column;
    gap: 12px;
  }
  
  .dialog-actions .btn {
    width: 100%;
  }
}
</style>


